package com.topisv.tms.service.yunda;

import java.io.StringWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.xml.bind.JAXB;

import org.apache.http.NameValuePair;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Response;
import org.apache.http.message.BasicNameValuePair;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.EdiOrderItem;
import com.topisv.tms.entity.ExpressConfigure;
import com.topisv.tms.entity.WarehouseAddress;
import com.topisv.tms.entity.work.WorkOrder;
import com.topisv.tms.service.ConsignorService;
import com.topisv.tms.service.ExpressConfigureService;
import com.topisv.tms.service.WarehouseAddressService;
import com.topisv.tms.service.vo.yunda.Consignor;
import com.topisv.tms.service.vo.yunda.OrderInfo;
import com.topisv.tms.service.vo.yunda.OrderInfos;
import com.topisv.tms.service.vo.yunda.OrderItem;
import com.topisv.tms.service.vo.yunda.OrderResponses;
import com.topisv.tms.service.vo.yunda.ReceiverResponse;
import com.topisv.tms.service.vo.yunda.ReceiverResponses;
import com.topisv.tms.service.vo.yunda.RequestType;
import com.topisv.tms.utils.SystemUtil;

/**
 * 韵达电子面单service
 *  Date          Author       Version       Description
 * ----------------------------------------------------------
 *  2015-7-30      CC            1.0           Create
 */
@Component
public class YUNDAService {
	protected static Logger log = LoggerFactory.getLogger(YUNDAService.class);
	@Autowired
	private WarehouseAddressService warehouseAddressService;
	@Autowired
	private ConsignorService consignorService;
	@Autowired
	private ExpressConfigureService expressConfigureService;

	public OrderResponses createYunDaOrder(WorkOrder order) {
		try {
			WarehouseAddress warehouse = warehouseAddressService.findByWarehouseCode(order.getWarehouseCode());
			com.topisv.tms.entity.Consignor consignor = consignorService.findCustomerCode(order.getCustomerCode());
			ExpressConfigure expressConfigure = expressConfigureService.findByWarehouseAndCompany(order.getWarehouseCode(), "YUNDA");
			String xmlData = build(order, warehouse, consignor);
			String subXML = xmlData.substring(XML_HEAD.length());
			Response response = sendOut2YUNDA(subXML, expressConfigure, RequestType.ORDER);
			return JAXB.unmarshal(response.returnContent().asStream(), OrderResponses.class);
		} catch (Exception e) {
			log.error("error", e);
		}
		return null;
	}

	public boolean checkArrive(EdiOrder order) {
		try {
			String xmlData = bulidCheckXml(order);
			ExpressConfigure expressConfigure = expressConfigureService.findByWarehouseAndCompany(order.getWarehouseCode(), "YUNDA");
			Response response = sendOut2YUNDA(xmlData, expressConfigure, RequestType.CHECK_URL);
			ReceiverResponses responses = JAXB.unmarshal(response.returnContent().asStream(), ReceiverResponses.class);
			List<ReceiverResponse> receiverResponses = responses.getReceiverResponses();
			if (receiverResponses != null && !receiverResponses.isEmpty()) {
				ReceiverResponse curReceive = receiverResponses.get(0);
				return "1".equals(curReceive.getReach());
			}
		} catch (Exception e) {
			log.error("error", e);
		}
		return false;
	}

	private String bulidCheckXml(EdiOrder order) {
		StringBuilder sb = new StringBuilder();
		sb.append("<orders>");
		sb.append("<order>");
		sb.append("<id>");
		sb.append(order.getOrdeno());
		sb.append("</id>");
		sb.append("<receiver_address>");
		sb.append(order.getAddres());
		sb.append("</receiver_address>");
		sb.append("</order>");
		sb.append("</orders>");
		return sb.toString();
	}

	public String build(WorkOrder workOrder, WarehouseAddress warehouse, com.topisv.tms.entity.Consignor consignor) {
		EdiOrder order = workOrder.getOrder();
		OrderInfos orders = new OrderInfos();
		List<OrderInfo> infos = new ArrayList<OrderInfo>();
		orders.setOrderInfos(infos);
		OrderInfo info = new OrderInfo();
		infos.add(info);

		info.setOrderSerialNo(order.getOrdeno());
		info.setKhddh(order.getOrdeno());
		// info.setNbckh(model.getOrdeno());
		info.setWaveNo(workOrder.getTaskCode());
		Consignor sender = new Consignor();
		sender.setName("派友云仓");
		sender.setCompany("派友电子商务");
		sender.setAddress(warehouse.getAddress());
		sender.setCity(new StringBuilder().append(warehouse.getProvName()).append(",").append(warehouse.getCityName()).append(",").append(warehouse.getDistName()).toString());
		if (consignor != null) {
			sender.setMobile(consignor.getMobile());
			sender.setPhone(consignor.getMobile());
		} else {
			sender.setMobile(warehouse.getMobile());
			sender.setPhone(warehouse.getMobile());
		}
		info.setSender(sender);

		Consignor receiver = new Consignor();
		receiver.setName(order.getRecena());
		// receiver.setCompany();
		receiver.setAddress(order.getAddres());
		receiver.setCity(new StringBuilder().append(order.getProvna()).append(",").append(order.getCityna()).append(",").append(order.getDistna()).toString());
		receiver.setMobile(order.getMobile());
		receiver.setPhone(order.getTeleph());
		info.setReceiver(receiver);

		List<OrderItem> items = new ArrayList<OrderItem>();
		info.setItems(items);
		StringBuilder itemInfo = new StringBuilder("订单详情: ");
		for (EdiOrderItem orderItem : order.getOrderItems()) {
			OrderItem item = new OrderItem();
			item.setName(orderItem.getSku());
			item.setNumber(orderItem.getQty());
			items.add(item);
			itemInfo.append(orderItem.getSku());
			itemInfo.append("(");
			itemInfo.append(orderItem.getQty());
			itemInfo.append(")\n");
		}
		itemInfo.append("\n").append(workOrder.getBatchCode()).append("_").append(workOrder.getTaskCode()).append("_").append(workOrder.getRankno());
		itemInfo.append("\n").append(order.getShopna()).toString();
		info.setCusArea1(itemInfo.toString());
		StringWriter sw = new StringWriter();
		JAXB.marshal(orders, sw);

		return sw.toString();
	}
    
	public Response sendOut2YUNDA(String xmlData, ExpressConfigure expressConfigure, RequestType requestType) {
		String base64xml = SystemUtil.getBASE64(xmlData);
		String userName = expressConfigure.getAccount();
		String pwd = expressConfigure.getPassword();
		String md5Validation = SystemUtil.MD5(base64xml + userName + pwd);
		String url = null;
		switch (requestType) {
		case ORDER:
			url = expressConfigure.getUrl() + ORDER_URL;
			break;
		case CANCEL_ORDER:
			url = expressConfigure.getUrl() + CANCEL_URL;
			break;
		case CHECK_URL:
			url = expressConfigure.getUrl() + CHECK_URL;
			break;
		}
		try {
			NameValuePair partneridPair = new BasicNameValuePair("partnerid", userName);
			NameValuePair validationPair = new BasicNameValuePair("validation", md5Validation);
			NameValuePair requestPair = new BasicNameValuePair("request", requestType.getType());
			NameValuePair xmldataPair = new BasicNameValuePair("xmldata", base64xml);
			NameValuePair versionPair = new BasicNameValuePair("version", "1.0");
			return Request.Post(url).connectTimeout(10000).bodyForm(Arrays.asList(partneridPair, validationPair, requestPair, xmldataPair, versionPair), Charset.forName("UTF-8")).execute();
		} catch (Exception e) {
			log.error("error", e);
		}
		return null;
	}

	private static final String CANCEL_URL = "/cus_order/order_interface/interface_cancel_order.php";
	private static final String ORDER_URL = "/cus_order/order_interface/interface_receive_order__mailno.php";
	private static final String CHECK_URL = "/cus_order/order_interface/interface_new_package.php";
	private static final String XML_HEAD = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?>";
}
